<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML>
<HEAD>
<TITLE>80386 Programmer's Reference Manual -- Section 3.4</TITLE>
</HEAD>
<BODY STYLE="width:80ch">
<B>up:</B> <A HREF="c03.htm">
Chapter 3 -- Applications Instruction Set</A><BR>
<B>prev:</B> <A HREF="s03_03.htm">3.3  Decimal Arithmetic Instructions</A><BR>
<B>next:</B> <A HREF="s03_05.htm">3.5  Control Transfer Instructions</A>
<P>
<HR>
<P>
<H1>3.4  Logical Instructions</H1>
The group of logical instructions includes:
<UL>
<LI> The Boolean operation instructions
<LI> Bit test and modify instructions
<LI> Bit scan instructions
<LI> Rotate and shift instructions
<LI> Byte set on condition
</UL>
<H2>3.4.1  Boolean Operation Instructions</H2>
The logical operations are <A HREF="AND.htm">AND</A>, 
<A HREF="OR.htm">OR</A>, 
<A HREF="XOR.htm">XOR</A>, and 
<A HREF="NOT.htm">NOT</A>.
<P>
<A HREF="NOT.htm">NOT</A> (Not) 
inverts the bits in the specified operand to form a one's
complement of the operand. The 
<A HREF="NOT.htm">NOT</A> instruction is a unary operation that
uses a single operand in a register or memory. 
<A HREF="NOT.htm">NOT</A> has no effect on the
flags.
<P>
The 
<A HREF="AND.htm">AND</A>, 
<A HREF="OR.htm">OR</A>, and 
<A HREF="XOR.htm">XOR</A> instructions perform the standard logical operations
"and", "(inclusive) or", and "exclusive or". These instructions can use the
following combinations of operands:
<UL>
<LI> Two register operands
<LI> A general register operand with a memory operand
<LI> An immediate operand with either a general register operand or a
memory operand.
</UL>
<A HREF="AND.htm">AND</A>, 
<A HREF="OR.htm">OR</A>, and 
<A HREF="XOR.htm">XOR</A> clear OF and CF, leave AF undefined, 
and update SF, ZF, and PF.

<H2>3.4.2  Bit Test and Modify Instructions</H2>
This group of instructions operates on a single bit which can be in memory
or in a general register. The location of the bit is specified as an offset
from the low-order end of the operand. The value of the offset either may be
given by an immediate byte in the instruction or may be contained in a
general register.
<P>
These instructions first assign the value of the selected bit to CF, the
carry flag. Then a new value is assigned to the selected bit, as determined
by the operation. OF, SF, ZF, AF, PF are left in an undefined state. Table
3-1 defines these instructions.
<PRE>
Table 3-1. Bit Test and Modify Instructions

Instruction                      Effect on CF            Effect on
                                                         Selected Bit

Bit (Bit Test)                   CF := BIT                (none)
BTS (Bit Test and Set)           CF := BIT                BIT := 1
BTR (Bit Test and Reset)         CF := BIT                BIT := 0
BTC (Bit Test and Complement)    CF := BIT                BIT := NOT(BIT)
</PRE>

<H2>3.4.3  Bit Scan Instructions</H2>
These instructions scan a word or doubleword for a one-bit and store the
index of the first set bit into a register.  The bit string being scanned
may be either in a register or in memory. The ZF flag is set if the entire
word is zero (no set bits are found); ZF is cleared if a one-bit is found.
If no set bit is found, the value of the destination register is undefined.
<P>
<A HREF="BSF.htm">BSF</A> (Bit Scan Forward) 
scans from low-order to high-order (starting from bit index zero).
<P>
<A HREF="BSR.htm">BSR</A> (Bit Scan Reverse) 
scans from high-order to low-order (starting from
bit index 15 of a word or index 31 of a doubleword).

<H2>3.4.4  Shift and Rotate Instructions</H2>
The shift and rotate instructions reposition the bits within the specified
operand.
<P>
These instructions fall into the following classes:
<UL>
<LI> Shift instructions
<LI> Double shift instructions
<LI> Rotate instructions
</UL>

<H3>3.4.4.1  Shift Instructions</H3>
The bits in bytes, words, and doublewords may be shifted arithmetically or
logically. Depending on the value of a specified count, bits can be shifted
up to 31 places.
<P>
A shift instruction can specify the count in one of three ways. One form of
shift instruction implicitly specifies the count as a single shift. The
second form specifies the count as an immediate value. The third form
specifies the count as the value contained in CL. This last form allows the
shift count to be a variable that the program supplies during execution.
Only the low order 5 bits of CL are used.
<P>
CF always contains the value of the last bit shifted out of the destination
operand. In a single-bit shift, OF is set if the value of the high-order
(sign) bit was changed by the operation. Otherwise, OF is cleared. Following
a multibit shift, however, the content of OF is always undefined.
<P>
The shift instructions provide a convenient way to accomplish division or
multiplication by binary power. Note however that division of signed numbers
by shifting right is not the same kind of division performed by the 
<A HREF="IDIV.htm">IDIV</A> instruction.
<P>
<A HREF="SAL.htm">SAL</A> (Shift Arithmetic Left) 
shifts the destination byte, word, or
doubleword operand left by one or by the number of bits specified in the
count operand (an immediate value or the value contained in CL). The
processor shifts zeros in from the right (low-order) side of the operand as
bits exit from the left (high-order) side. See 
<A HREF="s03_04.htm#fig3-6">Figure 3-6</A>.
<P>
<A HREF="SAL.htm">SHL</A> (Shift Logical Left) 
is a synonym for <A HREF="SAL.htm">SAL</A> (refer to <A HREF="SAL.htm">SAL</A>).
<P>
<A HREF="SAL.htm">SHR</A> (Shift Logical Right) shifts the destination byte, 
word, or doubleword
operand right by one or by the number of bits specified in the count operand
(an immediate value or the value contained in CL). The processor shifts
zeros in from the left side of the operand as bits exit from the right side.
See 
<A HREF="s03_04.htm#fig3-7">Figure 3-7</A>.
<P>
<A HREF="SAL.htm">SAR</A> (Shift Arithmetic Right) 
shifts the destination byte, word, or
doubleword operand to the right by one or by the number of bits specified in
the count operand (an immediate value or the value contained in CL). The
processor preserves the sign of the operand by shifting in zeros on the left
(high-order) side if the value is positive or by shifting by ones if the
value is negative. See 
<A HREF="s03_04.htm#fig3-8">Figure 3-8</A>.
<P>
Even though this instruction can be used to divide integers by a power of
two, the type of division is not the same as that produced by the 
<A HREF="IDIV.htm">IDIV</A>
instruction. The quotient of 
<A HREF="IDIV.htm">IDIV</A> is rounded toward zero, whereas the
"quotient" of 
<A HREF="SAL.htm">SAR</A> is rounded toward negative infinity. 
This difference is
apparent only for negative numbers. For example, when 
<A HREF="IDIV.htm">IDIV</A> is used to divide
-9 by 4, the result is -2 with a remainder of -1. If 
<A HREF="SAL.htm">SAR</A> is used to shift
-9 right by two bits, the result is -3. The "remainder" of this kind of
division is +3; however, the 
<A HREF="SAL.htm">SAR</A> instruction stores only the high-order bit
of the remainder (in CF).
<P>
The code sequence in 
<A HREF="s03_04.htm#fig3-9">Figure 3-9</A>
  produces the same result as 
<A HREF="IDIV.htm">IDIV</A> for any M = 2^(N), where 0 < N < 32. 
This sequence takes about 12 to 18 clocks,
depending on whether the jump is taken; if ECX contains M, the corresponding
<A HREF="IDIV.htm">IDIV</A> ECX instruction will take about 43 clocks.
<P>
<A NAME="fig3-6">
<PRE>Figure 3-6.  SAL and SHL</PRE>
<P>
<PRE>
                     OF   CF                OPERAND

       BEFORE SHL    X    X     10001000100010001000100010001111
       OR SAL

       AFTER SHL     1    1 <-- 00010001000100010001000100011110 <-- 0
       OR SAL BY 1

       AFTER SHL     X    0 <-- 00100010001000100011110000000000 <-- 0
       OR SAL BY 10
</PRE>
<P>
<HR>
<P>
<A NAME="fig3-7">
<PRE>Figure 3-7.  SHR</PRE>
<P>
<PRE>
                                      OPERAND                  CF

       BEFORE SHR         10001000100010001000100010001111     X

       AFTER SHR    0---->01000100010001000100010001000111---->1
       BY 1

       AFTER SHR    0---->00000000001000100010001000100010---->O
       BY 10
</PRE>
<P>
<HR>
<P>
<A NAME="fig3-8">
<PRE>Figure 3-8.  SAR</PRE>
<P>
<PRE>
                                  POSITIVE OPERAND             CF

       BEFORE SAR         01000100010001000100010001000111     X

       AFTER SAR    0---->00100010001000100010001000100011---->1
       BY 1

                                  NEGATIVE OPERAND             CF

       BEFORE SAR         11000100010001000100010001000111     X

       AFTER SAR    0---->11100010001000100010001000100011---->1
       BY 1
</PRE>
<P>
<HR>
<P>
<A NAME="fig3-9">
<PRE>Figure 3-9.  Using SAR to Simulate IDIV</PRE>
<P>
<PRE>
    ; assuming N is in ECX, and the dividend is in EAX
    ;                                               CLOCKS
    CMP     EAX, 0      ; to set sign flag          2
    JGE     NoAdjust    ; jump if sign is zero      3 or 9
    ADD     EAX, ECX    ;                           2
    DEC     EAX         ; EAX := EAX + (N-1)        2
NoAdjust:
    SAR     EAX, CL     ;                           3
    ;                       TOTAL CLOCKS           12 or 18]
</PRE>
<P>
<H3>3.4.4.2  Double-Shift Instructions</H3>
These instructions provide the basic operations needed to implement
operations on long unaligned bit strings. The double shifts operate either
on word or doubleword operands, as follows:
<OL>
<LI>Taking two word operands as input and producing a one-word output.
<LI>Taking two doubleword operands as input and producing a doubleword
output.
</OL>
Of the two input operands, one may either be in a general register or in
memory, while the other may only be in a general register. The results
replace the memory or register operand. The number of bits to be shifted is
specified either in the CL register or in an immediate byte of the
instruction.
<P>
Bits are shifted from the register operand into the memory or register
operand. CF is set to the value of the last bit shifted out of the
destination operand. SF, ZF, and PF are set according to the value of the
result. OF and AF are left undefined.
<P>
<A HREF="SHLD.htm">SHLD</A> (Shift Left Double) 
shifts bits of the R/M field to the left, while
shifting high-order bits from the Reg field into the R/M field on the right
(see 
<A HREF="s03_04.htm#fig3-10">Figure 3-10</A>). 
The result is stored back into the R/M operand. The Reg
field is not modified.
<P>
<A HREF="SHRD.htm">SHRD</A> (Shift Right Double) 
shifts bits of the R/M field to the right, while
shifting low-order bits from the Reg field into the R/M field on the left
(see 
<A HREF="s03_04.htm#fig3-11">Figure 3-11</A>). 
The result is stored back into the R/M operand. The Reg
field is not modified.

<H3>3.4.4.3  Rotate Instructions</H3>
Rotate instructions allow bits in bytes, words, and doublewords to be
rotated. Bits rotated out of an operand are not lost as in a shift, but are
"circled" back into the other "end" of the operand.
<P>
Rotates affect only the carry and overflow flags. CF may act as an
extension of the operand in two of the rotate instructions, allowing a bit
to be isolated and then tested by a conditional jump instruction (<A HREF="Jcc.htm">JC</A> or
<A HREF="Jcc.htm">JNC</A>). 
CF always contains the value of the last bit rotated out, even if the
instruction does not use this bit as an extension of the rotated operand.
<P>
In single-bit rotates, OF is set if the operation changes the high-order
(sign) bit of the destination operand. If the sign bit retains its original
value, OF is cleared. On multibit rotates, the value of OF is always
undefined.
<P>
<A HREF="RCL.htm">ROL</A> (Rotate Left) 
rotates the byte, word, or doubleword destination operand
left by one or by the number of bits specified in the count operand (an
immediate value or the value contained in CL). For each rotation specified,
the high-order bit that exits from the left of the operand returns at the
right to become the new low-order bit of the operand. See 
<A HREF="s03_04.htm#fig3-12">Figure 3-12</A>.
<P>
<A HREF="RCL.htm">ROR</A> (Rotate Right) 
rotates the byte, word, or doubleword destination
operand right by one or by the number of bits specified in the count operand
(an immediate value or the value contained in CL). For each rotation
specified, the low-order bit that exits from the right of the operand
returns at the left to become the new high-order bit of the operand.
See 
<A HREF="s03_04.htm#fig3-13">Figure 3-13</A>.
<P>
<A HREF="RCL.htm">RCL</A> (Rotate Through Carry Left) 
rotates bits in the byte, word, or
doubleword destination operand left by one or by the number of bits
specified in the count operand (an immediate value or the value contained in
CL).
<P>
This instruction differs from 
<A HREF="RCL.htm">ROL</A> in that it treats CF as a high-order
one-bit extension of the destination operand. Each high-order bit that exits
from the left side of the operand moves to CF before it returns to the
operand as the low-order bit on the next rotation cycle. See 
<A HREF="s03_04.htm#fig3-14">Figure 3-14</A>
  .
<P>
<A HREF="RCL.htm">RCR</A> (Rotate Through Carry Right) 
rotates bits in the byte, word, or
doubleword destination operand right by one or by the number of bits
specified in the count operand (an immediate value or the value contained in
CL).
<P>
This instruction differs from <A HREF="RCL.htm">ROR</A> in that it treats CF as a low-order
one-bit extension of the destination operand. Each low-order bit that exits
from the right side of the operand moves to CF before it returns to the
operand as the high-order bit on the next rotation cycle. See 
<A HREF="s03_04.htm#fig3-15">Figure 3-15</A>
  .
<P>
<A NAME="fig3-10">
<PRE>Figure 3-10.  Shift Left Double</PRE>
<P>
<PRE>
                  31                   DESTINATION                 0
    +----+       +--------------------------------------------------+
    | CF |<------|                 MEMORY OF REGISTER               |<---+
    +----+       +--------------------------------------------------+    |
             +-----------------------------------------------------------+
             |    31                     SOURCE                    0
             |   +--------------------------------------------------+
             +---|                      REGISTER                    |
                 +--------------------------------------------------+
</PRE>
<P>
<HR>
<P>
<A NAME="fig3-11">
<PRE>Figure 3-11.  Shift Right Double</PRE>
<P>
<PRE>
        31                     SOURCE                    0
       +--------------------------------------------------+
       |                      REGISTER                    |---+
       +--------------------------------------------------+   |
   +----------------------------------------------------------+
   |    31                   DESTINATION                 0
   |   +--------------------------------------------------+        +----+
   +-->|                 MEMORY OF REGISTER               |------->| CF |
       +--------------------------------------------------+        +----+
</PRE>
<P>
<HR>
<P>
<A NAME="fig3-12">
<PRE>Figure 3-12.  ROL</PRE>
<P>
<PRE>
                  31                   DESTINATION                 0
    +----+       +--------------------------------------------------+
    | CF |<---+--|                 MEMORY OF REGISTER               |<--+
    +----+    |  +--------------------------------------------------+   |
              +---------------------------------------------------------+
</PRE>
<P>
<HR>
<P>
<A NAME="fig3-13">
<PRE>Figure 3-13.  ROR</PRE>
<P>
<PRE>
     +----------------------------------------------------------+
     |    31                   DESTINATION                 0    |
     |   +--------------------------------------------------+   |    +----+
     +-->|                 MEMORY OF REGISTER               |---+--->| CF |
         +--------------------------------------------------+        +----+
</PRE>
<P>
<HR>
<P>
<A NAME="fig3-14">
<PRE>Figure 3-14.  RCL</PRE>
<P>
<PRE>
                  31                   DESTINATION                 0
    +----+       +--------------------------------------------------+
  +-| CF |<------|                 MEMORY OF REGISTER               |<--+
  | +----+       +--------------------------------------------------+   |
  +---------------------------------------------------------------------+
</PRE>
<P>
<HR>
<P>
<A NAME="fig3-15">
<PRE>Figure 3-15.  RCR</PRE>
<P>
<PRE>
   +----------------------------------------------------------------------+
   |    31                   DESTINATION                 0                |
   |   +--------------------------------------------------+        +----+ |
   +-->|                 MEMORY OF REGISTER               |------->| CF |-+
       +--------------------------------------------------+        +----+
</PRE>
<P>
<H3>3.4.4.4  Fast "BIT BLT" Using Double Shift Instructions</H3>
One purpose of the double shifts is to implement a bit string move, with
arbitrary misalignment of the bit strings.  This is called a "bit blt" (BIT
BLock Transfer.)  A simple example is to move a bit string from an arbitrary
offset into a doubleword-aligned byte string.  A left-to-right string is
moved 32 bits at a time if a double shift is used inside the move loop.
<PRE>
MOV   ESI,ScrAddr
MOV   EDI,DestAddr
MOV   EBX,WordCnt
MOV   CL,RelOffset      ; relative offset Dest-Src
MOV   EDX,[ESI]         ; load first word of source
ADD   ESI,4             ; bump source address
BltLoop:
LODS                    ; new low order part
SHLD  EDX,EAX,CL        ; EDX overwritten with aligned stuff
XCHG  EDX,EAS           ; Swap high/low order parts
STOS                    ; Write out next aligned chunk
DEC   EBX
JA    BltLoop
</PRE>
This loop is simple yet allows the data to be moved in 32-bit pieces for
the highest possible performance. Without a double shift, the best that can
be achieved is 16 bits per loop iteration by using a 32-bit shift and
replacing the 
<A HREF="XCHG.htm">XCHG</A> with a 
<A HREF="RCL.htm">ROR</A> by 16 to swap high and low order parts of
registers. A more general loop than shown above would require some extra
masking on the first doubleword moved (before the main loop), and on the
last doubleword moved (after the main loop), but would have the same basic
32-bits per loop iteration as the code above.

<H3>3.4.4.5  Fast Bit-String Insert and Extract</H3>
The double shift instructions also enable:
<UL>
<LI> Fast insertion of a bit string from a register into an arbitrary bit
location in a larger bit string in memory without disturbing the bits
on either side of the inserted bits.
<LI> Fast extraction of a bits string into a register from an arbitrary bit
location in a larger bit string in memory without disturbing the bits
on either side of the extracted bits.
</UL>
The following coded examples illustrate bit insertion and extraction under
variousconditions:
<OL>
<LI>Bit String Insert into Memory (when bit string is 1-25 bits long,
i.e., spans four bytes or less):
<PRE>
; Insert a right-justified bit string from register into
; memory bit string.
;
; Assumptions:
; 1) The base of the string array is dword aligned, and
; 2) the length of the bit string is an immediate value
;    but the bit offset is held in a register.
;
; Register ESI holds the right-justified bit string
; to be inserted.
; Register EDI holds the bit offset of the start of the
; substring.
; Registers EAX and ECX are also used by this
; "insert" operation.
;
MOV   ECX,EDI      ; preserve original offset for later use
SHR   EDI,3        ; signed divide offset by 8 (byte address)
AND   CL,7H        ; isolate low three bits of offset in CL
MOV   EAX,[EDI]strg_base      ; move string dword into EAX
ROR   EAX,CL       ; right justify old bit field
SHRD  EAX,ESI,length          ; bring in new bits
ROL   EAX,length   ; right justify new bit field
ROL   EAX,CL       ; bring to final position
MOV   [EDI]strg_base,EAX      ; replace dword in memory
</PRE>
<LI>Bit String Insert into Memory (when bit string is 1-31 bits long, i.e.
spans five bytes or less):
<PRE>
; Insert a right-justified bit string from register into
; memory bit string.
;
; Assumptions:
; 1) The base of the string array is dword aligned, and
; 2) the length of the bit string is an immediate value
;    but the bit offset is held in a register.
;
; Register ESI holds the right-justified bit string
; to be inserted.
; Register EDI holds the bit offset of the start of the
; substring.
; Registers EAX, EBX, ECX, and EDI are also used by
; this "insert" operation.
;
MOV   ECX,EDI     ; temp storage for offset
SHR   EDI,5       ; signed divide offset by 32 (dword address)
SHL   EDI,2       ; multiply by 4 (in byte address format)
AND   CL,1FH      ; isolate low five bits of offset in CL
MOV   EAX,[EDI]strg_base      ; move low string dword into EAX
MOV   EDX,[EDI]strg_base+4    ; other string dword into EDX
MOV   EBX,EAX     ; temp storage for part of string     + rotate
SHRD  EAX,EDX,CL  ; double shift by offset within dword + EDX:EAX
SHRD  EAX,EBX,CL  ; double shift by offset within dword + right
SHRD  EAX,ESI,length          ; bring in new bits
ROL   EAX,length  ; right justify new bit field
MOV   EBX,EAX     ; temp storage for part of string         + rotate
SHLD  EAX,EDX,CL  ; double shift back by offset within word + EDX:EAX
SHLD  EDX,EBX,CL  ; double shift back by offset within word + left
MOV   [EDI]strg_base,EAX      ; replace dword in memory
MOV   [EDI]strg_base+4,EDX    ; replace dword in memory
</PRE>
<LI>Bit String Insert into Memory (when bit string is exactly 32 bits
long, i.e., spans five or four types of memory):
<PRE>
; Insert right-justified bit string from register into
; memory bit string.
;
; Assumptions:
; 1) The base of the string array is dword aligned, and
; 2) the length of the bit string is 32
;    but the bit offset is held in a register.
;
; Register ESI holds the 32-bit string to be inserted.
; Register EDI holds the bit offset of the start of the
; substring.
; Registers EAX, EBX, ECX, and EDI are also used by
; this "insert" operation.
;
MOV   EDX,EDI     ; preserve original offset for later use
SHR   EDI,5       ; signed divide offset by 32 (dword address)
SHL   EDI,2       ; multiply by 4 (in byte address format)
AND   CL,1FH      ; isolate low five bits of offset in CL
MOV   EAX,[EDI]strg_base      ; move low string dword into EAX
MOV   EDX,[EDI]strg_base+4    ; other string dword into EDX
MOV   EBX,EAX     ; temp storage for part of string     + rotate
SHRD  EAX,EDX     ; double shift by offset within dword + EDX:EAX
SHRD  EDX,EBX     ; double shift by offset within dword + right
MOV   EAX,ESI     ; move 32-bit bit field into position
MOV   EBX,EAX     ; temp storage for part of string         + rotate
SHLD  EAX,EDX     ; double shift back by offset within word + EDX:EAX
SHLD  EDX,EBX     ; double shift back by offset within word + left
MOV   [EDI]strg_base,EAX      ; replace dword in memory
MOV   [EDI]strg_base,+4,EDX   ; replace dword in memory
</PRE>
<LI>Bit String Extract from Memory (when bit string is 1-25 bits long,
i.e., spans four bytes or less):
<PRE>
; Extract a right-justified bit string from memory bit
; string into register
;
; Assumptions:
; 1) The base of the string array is dword aligned, and
; 2) the length of the bit string is an immediate value
;    but the bit offset is held in a register.
;
; Register EAX holds the right-justified, zero-padded
; bit string that was extracted.
; Register EDI holds the bit offset of the start of the
; substring.
; Registers EDI, and ECX are also used by this "extract."
;
MOV  ECX,EDI      ; temp storage for offset
SHR  EDI,3        ; signed divide offset by 8 (byte address)
AND  CL,7H        ; isolate low three bits of offset
MOV  EAX,[EDI]strg_base       ; move string dword into EAX
SHR  EAX,CL       ; shift by offset within dword
AND  EAX,mask     ; extracted bit field in EAX
</PRE>
<LI>Bit String Extract from Memory (when bit string is 1-32 bits long,
i.e., spans five bytes or less):
<PRE>
; Extract a right-justified bit string from memory bit
; string into register.
;
; Assumptions:
; 1) The base of the string array is dword aligned, and
; 2) the length of the bit string is an immediate
;    value but the bit offset is held in a register.
;
; Register EAX holds the right-justified, zero-padded
; bit string that was extracted.
; Register EDI holds the bit offset of the start of the
; substring.
; Registers EAX, EBX, and ECX are also used by this "extract."
MOV   ECX,EDI     ; temp storage for offset
SHR   EDI,5       ; signed divide offset by 32 (dword address)
SHL   EDI,2       ; multiply by 4 (in byte address format)
AND   CL,1FH      ; isolate low five bits of offset in CL
MOV   EAX,[EDI]strg_base      ; move low string dword into EAX
MOV   EDX,[EDI]strg_base+4    ; other string dword into EDX
SHRD  EAX,EDX,CL  ; double shift right by offset within dword
AND   EAX,mask    ; extracted bit field in EAX
</PRE>
</OL>

<H2>3.4.5  Byte-Set-On-Condition Instructions</H2>
This group of instructions sets a byte to zero or one depending on any of
the 16 conditions defined by the status flags. The byte may be in memory or
may be a one-byte general register. These instructions are especially useful
for implementing Boolean expressions in high-level languages such as Pascal.
<P>
<A HREF="SETcc.htm">SETcc</A> (Set Byte on Condition cc) 
set a byte to one if condition cc is true;
sets the byte to zero otherwise. Refer to Appendix D for a definition of
the possible conditions.

<H2>3.4.6  Test Instruction</H2>
<A HREF="TEST.htm">TEST</A> (Test) 
performs the logical "and" of the two operands, clears OF and
CF, leaves AF undefined, and updates SF, ZF, and PF. The flags can be tested
by conditional control transfer instructions or by the byte-set-on-condition
instructions. The operands may be doublewords, words, or bytes.
<P>
The difference between 
<A HREF="TEST.htm">TEST</A> and 
<A HREF="AND.htm">AND</A> is that <A HREF="TEST.htm">TEST</A> 
does not alter the destination operand. 
<A HREF="TEST.htm">TEST</A> differs from <A HREF="BT.htm">BT</A> in that 
<A HREF="TEST.htm">TEST</A> is useful for testing
the value of multiple bits in one operations, whereas 
<A HREF="BT.htm">BT</A> tests a single bit.
<P>
<HR>
<P>
<B>up:</B> <A HREF="c03.htm">
Chapter 3 -- Applications Instruction Set</A><BR>
<B>prev:</B> <A HREF="s03_03.htm">3.3  Decimal Arithmetic Instructions</A><BR>
<B>next:</B> <A HREF="s03_05.htm">3.5  Control Transfer Instructions</A>
</BODY>
